/*
 *
 * System2 Simulation Framework
 * Copyright (C) 2011 - 2012 Jacob Dawid
 * jacob.dawid@googlemail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "packagemanager.h"
#include "blockgraphicsitem.h"
#include "simulationlayerview.h"
#include "simulationview.h"
#include <iostream>

namespace System2 {
    SimulationLayerView::SimulationLayerView(SimulationLayer *simulationLayer, QWidget *parent)
        : QGraphicsView(parent) {
        m_simulationLayer = simulationLayer;
        m_graphicsScene = new QGraphicsScene();
        setScene(m_graphicsScene);
        setAcceptDrops(true);
        setDragMode(QGraphicsView::RubberBandDrag);
        setOptimizationFlag(QGraphicsView::DontSavePainterState);
        setInteractive(true);
        m_scale = 1.0;
    }

    SimulationLayerView::~SimulationLayerView() {
        delete m_graphicsScene;
    }

    void SimulationLayerView::dragEnterEvent(QDragEnterEvent *event) {
        event->accept();
        /*
          TODO: This is very slow!
        if(event->mimeData()->hasFormat("application/x-s2-component")) {
            event->accept();
        } else {
            event->ignore();
        }
        */
    }

    void SimulationLayerView::dragLeaveEvent(QDragLeaveEvent *event) {
        event->ignore();
    }

    void SimulationLayerView::dragMoveEvent(QDragMoveEvent *event) {
        event->accept();
    }

    void SimulationLayerView::dropEvent(QDropEvent *event) {
        const QMimeData *mimeData = event->mimeData();
        if(mimeData->hasFormat("application/x-s2-component")) {
            QByteArray signature = mimeData->data("application/x-s2-component");

            Component *component
                    = PackageManager::instance()
                        ->componentBySignature(QString::fromAscii(signature));

            if(component) {
                Block *block = m_simulationLayer->addBlock(component);
                BlockGraphicsItem *blockGraphicsItem = new BlockGraphicsItem(block);

                m_graphicsScene->addItem(blockGraphicsItem);
                blockGraphicsItem->setPos(mapToScene(event->pos()));

                event->accept();
                return;
            }
        }

        event->ignore();
    }

    void SimulationLayerView::wheelEvent(QWheelEvent *event) {
        (void)event;
    }

    void SimulationLayerView::drawBackground(QPainter *painter, const QRectF &rect) {
        painter->setPen(QPen(QBrush(QColor(180, 180, 180)), 1.0, Qt::DotLine));
        int yStep = 82;
        int xStep = 120;

        qreal yStart = (int)rect.top() - yStep / 2;
        yStart -= (int)yStart % yStep;
        yStart = yStart > rect.left() ? (yStart - yStep) : yStart;
        for(qreal y = yStart - yStep / 2; y < rect.bottom(); y += yStep) {
           painter->drawLine(rect.left(), y, rect.right(), y);
        }

        qreal xStart = (int)rect.left() - xStep / 2;
        xStart -= (int)xStart % xStep;
        xStart = yStart > rect.left() ? (xStart - xStep) : xStart;
        for(qreal x = xStart - xStep / 2; x < rect.right(); x += xStep) {
           painter->drawLine(x, rect.top(), x, rect.bottom());
        }
    }
}
